<?php
// +---------------------------------------------------------------
// | Package: Tommy Framework
// +---------------------------------------------------------------
// | Version $Id:Controller.class.php 2010-3-30 12:30:30 $
// +---------------------------------------------------------------
// | Copyright (c) 2009 http://www.tommyframework.com All rights reserved.
// +---------------------------------------------------------------
// | Author: tommy <service@tommyframework.com>
// +---------------------------------------------------------------

/**
 +------------------------------------------------------------------------------
 * Tommy FrameworkAction控制器基类 抽象类
 +------------------------------------------------------------------------------ 
 */

if(!defined('IN_TOMMY')){
	exit;
}
abstract class Controller extends Base{
	
	//定义变量
	protected static $view;	//模板实例化变量
	protected $cache;	//页面缓存.
	protected $caching;	//页面缓存开启开关.

	/**
     +----------------------------------------------------------
     * 构造函数,用于初始化运行环境.
     +----------------------------------------------------------
     * @access public
     +----------------------------------------------------------
     * @return mixed
     +----------------------------------------------------------
     */
	public function __construct(){
		//初始化运行环境.
		$this->init();
		//实例化模板对象
		self::$view = View::getInstance();
		$this->caching = false;
		return true;
	}
	
	/**
     +----------------------------------------------------------
     * 模板变量赋值
     +----------------------------------------------------------
     * @access public
     +----------------------------------------------------------
     * @param mixed $name
     * @param mixed $value
     +----------------------------------------------------------
     */
	public function assign($key, $value=false){
		return self::$view->assign($key, $value);
	}
	
	/**
     +----------------------------------------------------------
     * 输出模板内容.
     +----------------------------------------------------------
     * @param string $filename 模板名称
     +----------------------------------------------------------
     * @return string
     +----------------------------------------------------------
     */
	public function display($filename=false){
		//当缓存没有开启时.
		if(!$this->caching){
			return self::$view->display($filename);
		}
		//当缓存开启时.
		if($this->cache->cache_on==true){
			ob_start();
			self::$view->display($filename);
			$content = ob_get_clean();
			echo $content;
			$this->cache->create_cache($content);
			return true;
		}
		else{
			return self::$view->display($filename);
		}
	}
	
	/**
     +----------------------------------------------------------
     * 处理页面缓存.
     +----------------------------------------------------------
     * @access public
     +----------------------------------------------------------
     * @param $expire 缓存周期
     * @param $filter  过滤字段
     +----------------------------------------------------------
     * @return mixed
     +----------------------------------------------------------
     */
	public function cache($expire=false, $filter=false){
		//实例化cache.
		$this->cache = Cache::getInstance();
		//参数处理.
		if($expire)
			$this->cache->lifetime = $expire;
		$this->cache->filter($filter);
		//加载缓存文件.
		$this->cache->load_cache();
		$this->caching = true;
		return true;
	}

	/**
     +----------------------------------------------------------
     * 设置caching的开关,从而避免不必要的缓存页面文件的生成.
     +----------------------------------------------------------
     * @access public
     +----------------------------------------------------------
     * @param string $state 缓存中否开启状态
     +----------------------------------------------------------
     * @return mixed
     +----------------------------------------------------------
     */
	public function set_cache($state=false){
		return $this->caching = $state ? true : false;
	}

	/**
     +----------------------------------------------------------
     * 获取网址(域名),如:http://www.tommyframework.com.
     +----------------------------------------------------------
     * @access public
     +----------------------------------------------------------
     * @return string
     +----------------------------------------------------------
     */
	public function get_server_name(){
		//获取网址域名部分.
		$server_name = !empty($_SERVER['HTTP_HOST']) ? strtolower($_SERVER['HTTP_HOST']) : $_SERVER['SERVER_NAME'];
		$server_port = ($_SERVER['SERVER_PORT'] == '80') ? '' : ':'.(int)$_SERVER['SERVER_PORT'];
		//获取网络协议.
		$secure = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on') ? 1 : 0;
		$server_url = (($secure) ? 'https://' : 'http://').$server_name.$server_port;
		return $server_url;
	}
	
	 /**
     +----------------------------------------------------------
     * 获取APP的根目录.用于网站前台js,css等文件所需的根目录的调用.
     +----------------------------------------------------------
     * @access public
     +----------------------------------------------------------
     * @return string
     +----------------------------------------------------------
     */
	public function get_base_url(){
		return str_replace(array('\\', '//'), array('', '/'), dirname($_SERVER['SCRIPT_NAME']));
	}
	
	/**
     +----------------------------------------------------------
     * 重组绝对路径的URL
     +----------------------------------------------------------
     * @param string $route controller与action
     * @param array $params URL路由其它字段
     +----------------------------------------------------------
     * @return string
     +----------------------------------------------------------
     */
	public function create_url($route, $params=false){
		//参数分析.
		if(empty($route)){
			return false;
		}
		$url = $this->get_base_url();
		$url .= (TOMMY_REWRITE == false) ? '/index.php/'.$route : '/'.$route;
		if(is_array($params)){
			$params_url = array();
			foreach($params as $key=>$value){
				$params_url[] = trim($key).'/'.trim($value);
			}
			$url .= '/'.implode('/', $params_url);
		}
		$url = str_replace('//', '/', $url);
		return $url;
	}
	
	/**
     +----------------------------------------------------------
     * 显示 程序错误信息.用于调试程序系统运行错误
     +----------------------------------------------------------
     * @access public
     +----------------------------------------------------------
     * @return string
     +----------------------------------------------------------
     */
	public function halt($string){		
		return trigger_error($string, E_USER_ERROR);
	}
	
	/**
     +----------------------------------------------------------
     * 显示页面信息,$go_url路径应为网站根目录.
     +----------------------------------------------------------
     * @param string $message 输出信息
     * @param string $go_url  所要跳转的URL
     * @param int $limit_time 所要等待的时间
     +----------------------------------------------------------
     * @return string
     +----------------------------------------------------------
     */
	public function show_message($message, $go_url, $limit_time=false){
		//参数分析.
		if(empty($message)){
			return false;
		}
		if($go_url=='-1'){			
			$limit_time = empty($limit_time) ? 5000 : 1000*$limit_time;
			$go_url = "javascript:history.go(-1);";
			$message .= "<br/>\n<a href=\"javascript:history.go(-1);\" target=\"_self\">如果你的浏览没反应,请点击这里...</a>\n";
		}
		else {			
			$limit_time = empty($limit_time) ? 1000 : 1000*$limit_time;
			$go_url = str_replace(array("\n","\r"), '', $go_url);
			$message .= "<br/>\n<a href=\"{$go_url}\" target=\"_self\">如果你的浏览没反应,请点击这里...</a>\n";
		}		
		$message .= "<script type=\"text/javascript\">\nfunction tommy_redirect_url(url){location.href=url;}setTimeout(\"tommy_redirect_url('{$go_url}')\", {$limit_time});\n</script>\n";		
		if(file_exists(APP_ROOT.'/themes/error/message.html')){
			$file_content = file_get_contents(APP_ROOT.'/themes/error/message.html');
		}
		else{
			$file_content = file_get_contents(TOMMY_ROOT.'/views/html/tommy_Message.html');
		}
		$file_content = str_replace(array('<!--{$message}-->', '<!-- {$message} -->'), $message, $file_content);
		echo $file_content;
		exit;
	}
	
	/**
     +----------------------------------------------------------
     * 页面跳转函数，例运行页面跳转到给定的网址即:URL重定向.
     +----------------------------------------------------------
     * @access public
     +----------------------------------------------------------
     * @param string $url 所要跳转的URL
     +----------------------------------------------------------
     * @return void
     +----------------------------------------------------------
     */
	public function redirect($url){
		//参数分析.
		if(empty($url)){
			return false;
		}		
		if(!headers_sent()){
			header("Location:".$url);
			exit;
		}
		else {
			echo '<script type="text/javascript">location.href="'.$url.'";</script>';
			exit;
		}
	}

	/**
     +----------------------------------------------------------
     * 系统调试完美输出数据函数 print_r().
     +----------------------------------------------------------
     * @param array $data  数据
     * @param string $option  是否用var_dump()
     +----------------------------------------------------------
     * @return array
     +----------------------------------------------------------
     */
	public function dump($data, $option=false){
		if($option){
			ob_start();
			var_dump($data);
			$output = ob_get_clean();
			$output = str_replace('"', '', $output);
			$output = preg_replace("/\]\=\>\n(\s+)/m", "] => ", $output);
			echo '<pre>', $output, '</pre>';
		}
		else{
			echo '<pre>';
			print_r($data);
			echo '</pre>';
		}

		exit;
	}
	
	/**
     +----------------------------------------------------------
     * 对$_POST获取的全局变量进行转义化处理，提升代码安全.
     +----------------------------------------------------------
     * @access public
     +----------------------------------------------------------
     * @param string $string 所要处理的参数
     +----------------------------------------------------------
     * @return string
     +----------------------------------------------------------
     */
	public function post($string){		
		if(is_array($string)){	
			foreach ($string as $key=>$value){
				$string[$key] = $this->post($value);
			}
			return $string;
		}
		else{
			return htmlspecialchars(trim($_POST[$string]));
		}
	}
	
	/**
     +----------------------------------------------------------
     * 对$_GET获取的全局变量进行转义化处理，提升代码安全.
     +----------------------------------------------------------
     * @access public
     +----------------------------------------------------------
     * @param string $string 所要处理的参数
     +----------------------------------------------------------
     * @return string
     +----------------------------------------------------------
     */
	public function get($string){		
		if(is_array($string)){
			foreach($string as $key=>$value){	
				$string[$key] = $this->get($value);
			}
			return $string;
		}
		else{
			return htmlspecialchars(trim($_GET[$string]));
		}
	}
	
	/**
     +----------------------------------------------------------
     * 类的单口实例化函数.
     +----------------------------------------------------------
     * @access public
     +----------------------------------------------------------
     * @param string $class_name 类名称
     +----------------------------------------------------------
     * @return object
     +----------------------------------------------------------
     */
	public static function instance($class_name){
		static $_instance = array();
		if(!isset($_instance[$class_name])){
			$_instance[$class_name] = new $class_name();
		}
		return $_instance[$class_name];
	}
	
	/**
     +----------------------------------------------------------
     * 用于实例化一个Model对象.
     +----------------------------------------------------------
     * @access public
     +----------------------------------------------------------
     * @param string $table_name 类名称
     +----------------------------------------------------------
     * @return object
     +----------------------------------------------------------
     */
	public static function model($table_name){
		static $model = array();
		$model_name = ucfirst(strtolower($table_name)).'Model';
		if($model[$model_name]==null){
			$model[$model_name] = new $model_name;
		}
		return $model[$model_name];
	}
	
	/**
     +----------------------------------------------------------
     * 加载文件 ,相当于inclue_once().
     +----------------------------------------------------------
     * @param string $file_name 文件名或路径
     * @param string $file_dir  文件目录
     +----------------------------------------------------------
     * @return string
     +----------------------------------------------------------
     */
	public function import($file_name, $file_dir = false){
		static $import_files = array();
		//参数分析.
		if(strpos($file_name, '/')){
			$file_url = realpath($file_name);
		}
		else{
			$file_dir = empty($file_dir) ? APP_ROOT.'/extensions' : $file_dir;
			$file_url = realpath($file_dir.'/'.$file_name.'/'.$file_name.'.class.php');
		}
		//文件分析,不存在时提示错误信息.
		if(!$file_url){
			$this->halt('The import file '.$file_name.' do not exists');
		}		
		if($import_files[$file_url]==false){
			include ($file_url);
			$import_files[$file_url] = true;
		}		
		return $import_files[$file_url];
	}
	
	/**
     +----------------------------------------------------------
     * 加载config目录中的配置文件
     +----------------------------------------------------------
     * @access public
     +----------------------------------------------------------
     * @param string $file_name 文件名
     +----------------------------------------------------------
     * @return string
     +----------------------------------------------------------
     */
	public function config_load($file_name){
		static $config_files = array();
		$config_file_path = APP_ROOT.'/config/'.$file_name.'.ini.php';
		//判断文件是否存在.
		if(!file_exists($config_file_path)){
			$this->halt('The config file: '.$config_file_path.' do not exists');
		}
		if($config_files[$config_file_path]==false){
			$config_files[$config_file_path] = include($config_file_path);
		}
		return $config_files[$config_file_path];
	}

	/**
     +----------------------------------------------------------
     * 加载并实例化module.
     +----------------------------------------------------------
     * @access public
     +----------------------------------------------------------
     * @param string $module_name 模块名称
     +----------------------------------------------------------
     * @return object
     +----------------------------------------------------------
     */
	public function module($module_name){
		//参数判断.
		if(empty($module_name)){
			return false;
		}
		static $_module_name = array();
		if($_module_name[$module_name]==null){
			//加载文件.		
			$this->import($module_name);
			$_module_name[$module_name] = $this->instance($module_name);
		}		
		return $_module_name[$module_name];
	}
	
	/**
     +----------------------------------------------------------
     * 获取themes文件的URL.
     +----------------------------------------------------------
     * @access public
     +----------------------------------------------------------
     * @param string $theme_name 主题名称
     +----------------------------------------------------------
     * @return string
     +----------------------------------------------------------
     */
	public function get_theme_url($theme_name=false){
		$theme_dir_name = empty($theme_name) ? 'default' : $theme_name;
		//判断是主题目录是否存在
		$theme_dir_path = APP_ROOT.'/themes/'.$theme_dir_name;
		if(!is_dir($theme_dir_path)){
			$this->halt('The themes dir: '.$theme_dir_path.' do not exists');
		}
		return $this->get_base_url().'/themes/'.$theme_dir_name;
	}

	/**
     +----------------------------------------------------------
     * 本函数相当于addslashes.批量处理addslashes数据.
     +----------------------------------------------------------
     * @access public
     +----------------------------------------------------------
     * @param string $string 所要处理的参数
     +----------------------------------------------------------
     * @return string
     +----------------------------------------------------------
     */
	protected function add_slashes($string){		
		if(is_array($string)){
			foreach ($string as $key=>$value){
				$string[$key] = $this->add_slashes($value);
			}
			return $string;
		}
		else {
			return addslashes($string);
		}
	}

	/**
     +----------------------------------------------------------
     * 相当于stripslashes()
     +----------------------------------------------------------
     * @access public
     +----------------------------------------------------------
     * @param string $string 所要处理的参数
     +----------------------------------------------------------
     * @return string
     +----------------------------------------------------------
     */
	protected function strip_slashes($string){		
		if(is_array($string)){
			foreach ($string as $key=>$value){	
				$string[$key] = $this->strip_slashes($value);
			}
			return $string;
		}
		else{
			return stripslashes($string);
		}
	}
	
	 /**
     +----------------------------------------------------------
     * 应用程序初始化
     +----------------------------------------------------------
     * @access public
     +----------------------------------------------------------
     * @return void
     +----------------------------------------------------------
     */
	private function init(){		 
		//设置时间区域,默认为中国.						
		date_default_timezone_set(TOMMY_TIMEZONE);
		//设置session数据存放目录
		if(file_exists(APP_ROOT.'/cache/temp')){
			session_save_path(APP_ROOT.'/cache/temp');
		}
		//关闭魔术变量，提高PHP运行效率.
		if(get_magic_quotes_runtime()){	
			set_magic_quotes_runtime(0);
		}
		//将全局变量进行魔术变量处理
		if(get_magic_quotes_gpc()){	
			$_COOKIE = $this->strip_slashes($_COOKIE);
		}
		else {
			$_POST = $this->add_slashes($_POST);
			$_GET = $this->add_slashes($_GET);
			$_SESSION = $this->add_slashes($_SESSION);
		}
		return true;
	}
}
?>